package com.baofu.paycore.manager.storage.impl;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.baofu.paycore.common.enums.RedisKeyEnum;
import com.baofu.paycore.common.enums.UsableFlagEnum;
import com.baofu.paycore.common.exception.PayCoreManagerException;
import com.baofu.paycore.common.utils.RedisKeyUtil;
import com.baofu.paycore.common.utils.Validate;
import com.baofu.paycore.manager.converter.DO2BOConverter;
import com.baofu.paycore.manager.model.RefundStrategyBO;
import com.baofu.paycore.manager.util.RefundCheckUtil;
import com.baofu.paycore.service.facade.enums.PayCoreErrorCode;
import com.system.commons.exception.BizServiceException;
import com.system.commons.utils.BeanCopyUtil;
import com.system.commons.utils.ParamValidate;
import com.baofu.paycore.dal.mapper.RefundProductStrategyMapper;
import com.baofu.paycore.dal.mapper.RefundStrategyMapper;
import com.baofu.paycore.dal.mapper.RefundStrategyModeMapper;
import com.baofu.paycore.dal.mapper.RefundStrategyPriorityMapper;
import com.baofu.paycore.dal.model.*;
import com.baofu.paycore.manager.cache.RedisManager;
import com.baofu.paycore.common.exception.ManagerErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

/**
 * 退款策略配置
 *
 * <p>
 * 1.分页获取退款策略信息
 * 2.新增退款策略信息
 * 3.修改退款策略信息
 * 4.删除退款策略信息
 * 5.获取退款策略优先级配置信息
 * 6.分页获取退款策略优先级配置信息
 * 7.新增退款策略优先级配置信息
 * 8.修改退款策略优先级配置信息
 * 9.删除退款策略优先级配置信息
 * 10.获取退款模式配置信息
 * 11.分页获取退款模式配置信息
 * 12.新增退款模式配置信息
 * 13.修改退款模式配置信息
 * 14.删除退款模式配置信息
 * 15.获取产品退款策略关联信息
 * 16.分页获取产品退款策略关联信息
 * 17.新增产品退款策略关联表信息
 * 18.修改产品退款策略关联表信息
 * 19.删除产品退款策略关联表信息
 * 20.查询产品对应的退货规则，包含优先级和模式
 * </p>
 * User: liu ting  Date: 2016/4/29 ProjectName: paycore Version: 1.0
 */
@Slf4j
@Repository
public class RefundStrategyManager {

    /**
     * 退款策略配置信息操作
     */
    @Autowired
    private RefundStrategyMapper refundStrategyMapper;

    /**
     * 退款策略配置优先级配置操作
     */
    @Autowired
    private RefundStrategyPriorityMapper refundStrategyPriorityMapper;

    /**
     * 退款模式配置信息配置操作
     */
    @Autowired
    private RefundStrategyModeMapper refundStrategyModeMapper;

    /**
     * 退款策略关联产品信息配置操作
     */
    @Autowired
    private RefundProductStrategyMapper refundProductStrategyMapper;

    /**
     * redis缓存操作
     */
    @Autowired
    private RedisManager redisManager;

    /**
     * redis缓存退款策略key
     */
    private static String keyStrategy = "PAYCORE:STRATEGY:";

    /**
     * redis缓存退款优先级key
     */
    private final String keyStrategyPriority = "PAYCORE:STRATEGY:PRIORITY:";

    /**
     * redis缓存退款模式key
     */
    private final String keyStrategyMode = "PAYCORE:STRATEGY:MODE:";

    /**
     * redis缓存退款关联产品key
     */
    private static final String keyStrategyProduct = "PAYCORE:STRATEGY:PRODUCT:";

    /**
     * 获取退款策略信息
     *
     * @return list
     */
    public List<RefundStrategyDO> selectRefundStrategy(RefundStrategyDO refundStrategyDO) {
        return refundStrategyMapper.selectInfo(refundStrategyDO);
    }

    /**
     * 分页获取退款策略信息
     *
     * @param refundStrategyDO 退款策略信息对象
     * @param beginPage        起始页
     * @param pageSize         每页显示数量
     * @return list
     */
    public List<RefundStrategyDO> selectRefundStrategyByPage(
            RefundStrategyDO refundStrategyDO, int beginPage, int pageSize) {

        List<RefundStrategyDO> list = refundStrategyMapper.selectInfoByPage(refundStrategyDO, beginPage, pageSize);
        ParamValidate.checkCollectSize(list, PayCoreErrorCode.REFUND_STRATEGY_IS_NULL);

        return list;
    }

    /**
     * 根据条件查询总记录数
     *
     * @param refundStrategyDO 传入对象
     * @return 返回记录数
     */
    public Integer selectRefundStrategyOfCount(RefundStrategyDO refundStrategyDO) {

        Integer count = refundStrategyMapper.selectInfoCount(refundStrategyDO);
        if (count < 1) {
            log.error("call RefundStrategyManager selectRefundStrategyOfCount refundStrategyDO:{}" + refundStrategyDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_STRATEGY_IS_NULL);
        }
        return count;
    }

    /**
     * 新增退款策略信息
     *
     * @param refundStrategyDO 退款策略信息对象
     */
    public void insertRefundStrategy(RefundStrategyDO refundStrategyDO) {
        int count = refundStrategyMapper.insert(refundStrategyDO);
        if (count < 1) {
            log.error("call RefundStrategyManager insertRefundStrategy refundStrategyDO:{}" + refundStrategyDO);
            throw new BizServiceException(PayCoreErrorCode.INSERT_DATA_NOT_NOE);
        }
    }

    /**
     * 修改退款策略信息
     *
     * @param refundStrategyDO 退款策略信息对象
     */
    public void updateRefundStrategy(RefundStrategyDO refundStrategyDO) {
        int count = refundStrategyMapper.update(refundStrategyDO);
        if (count < 1) {
            log.error("call RefundStrategyManager updateRefundStrategy refundStrategyDO:{}" + refundStrategyDO);
            throw new BizServiceException(PayCoreErrorCode.UPDATE_DATA_NOT_ONE);
        }
    }

    /**
     * 删除退款策略信息
     *
     * @param refundStrategyDO 退款策略信息对象
     */
    public void deleteRefundStrategy(RefundStrategyDO refundStrategyDO) throws Exception {

        int count = refundStrategyMapper.deleteInfo(refundStrategyDO.getUpdatedBy(), refundStrategyDO.getId());
        if (count < 1) {
            log.error("call RefundStrategyManager deleteRefundStrategy refundStrategyDO:{}" + refundStrategyDO);
            throw new BizServiceException(PayCoreErrorCode.UPDATE_DATA_NOT_ONE);
        }
        redisManager.deleteObject(keyStrategy + refundStrategyDO.getId());
    }

    /**
     * 获取退款策略优先级配置信息
     *
     * @param refundStrategyPriorityDO 退款策略优先级配置信息
     * @return 退款策略优先级配置信息
     */
    public List<RefundStrategyPriorityDO> selectRefundStrategyPriority(RefundStrategyPriorityDO
                                                                               refundStrategyPriorityDO) {
        return refundStrategyPriorityMapper.selectInfo(refundStrategyPriorityDO);
    }

    /**
     * 分页获取退款策略优先级配置信息
     *
     * @param refundStrategyPriorityDO 策略优先级配置信息对象
     * @param beginPage                开始页
     * @param pageSize                 每页显示记录数
     * @return 退款策略优先级配置信息
     */
    public List<RefundStrategyPriorityDO> selectRefundStrategyPriorityByPage(
            RefundStrategyPriorityDO refundStrategyPriorityDO, int beginPage, int pageSize) {

        return refundStrategyPriorityMapper.selectInfoByPage(refundStrategyPriorityDO,
                beginPage, pageSize);
    }

    /**
     * 获取退款策略优先级配置信息记录数
     * @param refundStrategyPriorityDO 退款策略优先级配置信息对象
     * @return 记录数
     */
    public Integer selectRefundStrategyPriorityCount(RefundStrategyPriorityDO refundStrategyPriorityDO){

        return refundStrategyPriorityMapper.selectInfoCount(refundStrategyPriorityDO);
    }

    /**
     * 新增退款策略优先级配置信息
     *
     * @param refundStrategyPriorityDO 策略优先级配置信息
     */
    public void insertRefundStrategyPriority(RefundStrategyPriorityDO refundStrategyPriorityDO) throws Exception {

        //新增前校验关联的策略是否存在
        RefundStrategyDO refundStrategyDO = new RefundStrategyDO();
        refundStrategyDO.setRefundStrategyPriority(refundStrategyPriorityDO.getRefundStrategyPriority());
        List<RefundStrategyDO> priorityList = selectRefundStrategy(refundStrategyDO);
        if (priorityList == null || priorityList.size() == 0) {
            log.error("call RefundStrategyManager insertRefundStrategyPriority refundStrategyPriorityDO: {}"
                    + refundStrategyPriorityDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_STRATEGY_IS_NULL);
        }
        //校验是否已存在此支付工具的优先级
        RefundStrategyPriorityDO priorityDO = new RefundStrategyPriorityDO();
        priorityDO.setRefundStrategyPriority(refundStrategyPriorityDO.getRefundStrategyPriority());
        priorityDO.setPayToolType(refundStrategyPriorityDO.getPayToolType());
        int priorityCount = refundStrategyPriorityMapper.selectInfoCount(priorityDO);
        if(priorityCount > 0){
            log.error("新增退款策略优先级失败，数据库中已存在此优先级配置，请求对象：{}", refundStrategyPriorityDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_PRIORITY_IS_EXIST);
        }
        int count = refundStrategyPriorityMapper.insert(refundStrategyPriorityDO);
        Validate.checkUpdate(count);
    }

    /**
     * 修改退款策略优先级配置信息
     *
     * @param refundStrategyPriorityDO 退款策略优先级配置信息对象
     */
    public void updateRefundStrategyPriority(RefundStrategyPriorityDO refundStrategyPriorityDO) {
        int count = refundStrategyPriorityMapper.update(refundStrategyPriorityDO);
        if (count < 1) {
            log.error("call RefundStrategyManager updateRefundStrategyPriority refundStrategyPriorityDO:{}"
                    + refundStrategyPriorityDO);
            throw new BizServiceException(PayCoreErrorCode.UPDATE_DATA_NOT_ONE);
        }
        redisManager.deleteObject(keyStrategyPriority + refundStrategyPriorityDO.getRefundStrategyPriority());
        RefundStrategyPriorityDO strategyPriorityDO = new RefundStrategyPriorityDO();
        strategyPriorityDO.setRefundStrategyPriority(refundStrategyPriorityDO.getRefundStrategyPriority());
        List<RefundStrategyPriorityDO> priorityDOList = refundStrategyPriorityMapper.selectInfo(strategyPriorityDO);
        redisManager.insertObject(priorityDOList, keyStrategyPriority
                + refundStrategyPriorityDO.getRefundStrategyPriority());

    }

    /**
     * 删除退款策略优先级配置信息
     *
     * @param refundStrategyPriorityDO 款策略优先级配置信息对象
     */
    public void deleteRefundStrategyPriority(RefundStrategyPriorityDO refundStrategyPriorityDO) throws Exception {

        int count = refundStrategyPriorityMapper.deleteInfo(
                refundStrategyPriorityDO.getUpdatedBy(), refundStrategyPriorityDO.getId());
        if (count < 1) {
            log.error("call RefundStrategyManager deleteRefundStrategyPriority refundStrategyPriorityDO:{}"
                    + refundStrategyPriorityDO);
            throw new BizServiceException(PayCoreErrorCode.UPDATE_DATA_NOT_ONE);
        }
        redisManager.deleteObject(keyStrategyPriority + refundStrategyPriorityDO.getRefundStrategyPriority());
        RefundStrategyPriorityDO strategyPriorityDO = new RefundStrategyPriorityDO();
        strategyPriorityDO.setRefundStrategyPriority(refundStrategyPriorityDO.getRefundStrategyPriority());
        List<RefundStrategyPriorityDO> priorityDOList = refundStrategyPriorityMapper.selectInfo(strategyPriorityDO);
        if (priorityDOList.size() > 0) {
            redisManager.insertObject(priorityDOList, keyStrategyPriority
                    + refundStrategyPriorityDO.getRefundStrategyPriority());
        }
    }

    /**
     * 获取退款模式配置信息
     *
     * @param refundStrategyModeDO 退款模式配置信息对象
     * @return list
     */
    public List<RefundStrategyModeDO> selectStrategyModeInfo(RefundStrategyModeDO refundStrategyModeDO) {
        List<RefundStrategyModeDO> list = refundStrategyModeMapper.selectInfo(refundStrategyModeDO);
        if(list.size() < 1){
            log.error("call RefundStrategyManager selectStrategyModeInfo refundStrategyModeDO:{}"
                    + refundStrategyModeDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_STRATEGY_MODE_IS_NULL);
        }
        return list;
    }

    /**
     * 分页获取退款模式配置信息
     *
     * @param refundStrategyModeDO 退款模式配置信息对象
     * @return 退款模式配置信息
     */
    public List<RefundStrategyModeDO> selectStrategyModeInfoByPage(RefundStrategyModeDO refundStrategyModeDO,
                                                                   int beginPage, int pageSize) {

        return refundStrategyModeMapper.selectInfoByPage(refundStrategyModeDO, beginPage,
                pageSize);
    }

    /**
     * 获取退款模式配置信息记录数
     *
     * @param refundStrategyModeDO 退款模式配置信息对象
     * @return 退款模式配置信息记录数
     */
    public Integer selectStrategyModeInfoCount(RefundStrategyModeDO refundStrategyModeDO){

        int count = refundStrategyModeMapper.selectInfoCount(refundStrategyModeDO);
        if(count < 1){
            log.error("call RefundStrategyManager selectStrategyModeInfo refundStrategyModeDO:{}"
                    + refundStrategyModeDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_STRATEGY_MODE_IS_NULL);
        }
        return count;
    }

    /**
     * 新增退款模式配置信息
     *
     * @param refundStrategyModeDO 退款模式配置信息对象
     */
    public void insertRefundStrategyMode(RefundStrategyModeDO refundStrategyModeDO) throws Exception {

        //校验退款模式信息中的退货策略配置id是否存在
        RefundStrategyDO refundStrategyDO = new RefundStrategyDO();
        refundStrategyDO.setRefundStrategyMode(refundStrategyModeDO.getRefundStrategyMode());
        List<RefundStrategyDO> list = selectRefundStrategy(refundStrategyDO);
        if (list == null || list.size() == 0) {
            log.error("call RefundStrategyManager insertRefundStrategyMode refundStrategyModeDO:{}"
                    + refundStrategyModeDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_STRATEGY_IS_NULL);
        }
        //判断此支付工具的退款模式是否已经配置
        RefundStrategyModeDO modeDO = new RefundStrategyModeDO();
        modeDO.setPayToolType(refundStrategyModeDO.getPayToolType());
        modeDO.setRefundStrategyMode(refundStrategyModeDO.getRefundStrategyMode());
        modeDO.setRefundTargetMode(refundStrategyModeDO.getRefundTargetMode());
        int modeCount = refundStrategyModeMapper.selectInfoCount(modeDO);
        if(modeCount > 0){
            log.error("新增退款策略模式失败，数据库中已存在此模式，参数refundStrategyModeDO：{}", refundStrategyModeDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_PRIORITY_MODE_IS_EXIST);
        }
        int count = refundStrategyModeMapper.insert(refundStrategyModeDO);
        if (count < 1) {
            log.error("call RefundStrategyManager insertRefundStrategyMode refundStrategyModeDO return:{}"
                    + refundStrategyModeDO);
            throw new BizServiceException(PayCoreErrorCode.INSERT_DATA_NOT_NOE);
        }
    }

    /**
     * 修改退款模式配置信息
     *
     * @param refundStrategyModeDO 退款模式配置信息对象
     */
    public void updateRefundStrategyMode(RefundStrategyModeDO refundStrategyModeDO) throws Exception {

        int count = refundStrategyModeMapper.update(refundStrategyModeDO);
        if (count < 1) {
            log.error("call RefundStrategyManager updateRefundStrategyMode refundStrategyModeDO :{}"
                    + refundStrategyModeDO);
            throw new BizServiceException(PayCoreErrorCode.UPDATE_DATA_NOT_ONE);
        }
        redisManager.deleteObject(keyStrategyMode + refundStrategyModeDO.getRefundStrategyMode());
        RefundStrategyModeDO strategyModeDO = new RefundStrategyModeDO();
        strategyModeDO.setRefundStrategyMode(refundStrategyModeDO.getRefundStrategyMode());
        List<RefundStrategyModeDO> strategyModeDOList = refundStrategyModeMapper.selectInfo(strategyModeDO);
        redisManager.insertObject(strategyModeDOList, keyStrategyMode + refundStrategyModeDO.getRefundStrategyMode());
    }

    /**
     * 删除退款模式配置信息
     *
     * @param refundStrategyModeDO 退款模式配置信息对象
     */
    public void deleteRefundStrategyMode(RefundStrategyModeDO refundStrategyModeDO) throws Exception {
        int count = refundStrategyModeMapper.deleteInfo(
                refundStrategyModeDO.getUpdatedBy(), refundStrategyModeDO.getId());
        if (count < 1) {
            log.error("call RefundStrategyManager deleteRefundStrategyMode refundStrategyModeDO :{}"
                    + refundStrategyModeDO);
            throw new BizServiceException(PayCoreErrorCode.UPDATE_DATA_NOT_ONE);
        }
        redisManager.deleteObject(keyStrategyMode + refundStrategyModeDO.getRefundStrategyMode());
        RefundStrategyModeDO strategyModeDO = new RefundStrategyModeDO();
        strategyModeDO.setRefundStrategyMode(refundStrategyModeDO.getRefundStrategyMode());
        List<RefundStrategyModeDO> strategyModeDOList = refundStrategyModeMapper.selectInfo(strategyModeDO);
        redisManager.insertObject(strategyModeDOList, keyStrategyMode + refundStrategyModeDO.getRefundStrategyMode());
    }

    /**
     * 获取产品退款策略关联信息
     *
     * @param refundProductStrategyDO 产品退款策略关联信息
     * @return 产品退款策略关联信息
     */
    public List<RefundProductStrategyDO> selectRefundProductStrategy(RefundProductStrategyDO refundProductStrategyDO) {
        return refundProductStrategyMapper.selectInfo(refundProductStrategyDO);
    }

    /**
     * 分页获取产品退款策略关联信息
     *
     * @param refundProductStrategyDO 产品退款策略关联信息
     * @param beginPage               开始页
     * @param pageSize                每页显示记录数
     * @return 产品退款策略关联信息
     */
    public List<RefundProductStrategyDO> selectRefundProductStrategyByPage(RefundProductStrategyDO refundProductStrategyDO,
                                                                           int beginPage, int pageSize) {
        return refundProductStrategyMapper.selectInfoByPage(refundProductStrategyDO, beginPage,
                pageSize);
    }

    /**
     * 获取产品退款策略关联信息记录数
     *
     * @param refundProductStrategyDO 产品退款策略关联信息对象
     * @return 产品退款策略关联信息记录数
     */
    public Integer selectRefundProductStrategyCount(RefundProductStrategyDO refundProductStrategyDO){
        int count = refundProductStrategyMapper.selectInfoCount(refundProductStrategyDO);
        if(count < 1){
            log.error("call RefundStrategyManager selectRefundProductStrategyCount refundProductStrategyDO :{}"
                    + refundProductStrategyDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_PRODUCT_PRIORITY_IS_NULL);
        }
        return count;
    }

    /**
     * 新增产品退款策略关联表信息
     *
     * @param refundProductStrategyDO 产品退款策略关联表信息
     * @throws Exception
     */
    public void insertRefundProductStrategy(RefundProductStrategyDO refundProductStrategyDO) throws Exception {
        //查询产品退款策略配置是否存在
        List<RefundProductStrategyDO> list = refundProductStrategyMapper.selectInfo(refundProductStrategyDO);
        if (list != null && list.size() > 0) {
            log.error("call RefundStrategyManager insertRefundProductStrategy refundProductStrategyDO:{}" + refundProductStrategyDO);
            throw new BizServiceException(PayCoreErrorCode.REFUND_PRODUCT_PRIORITY_IS_EXIST);
        }
        refundProductStrategyMapper.insert(refundProductStrategyDO);
    }

    /**
     * 修改产品退款策略关联表信息
     *
     * @param refundProductStrategyDO 产品退款策略关联表信息对象
     */
    public void updateRefundProductStrategy(RefundProductStrategyDO refundProductStrategyDO) {

        RefundProductStrategyDO productStrategyDO =
                refundProductStrategyMapper.selectById(String.valueOf(refundProductStrategyDO.getId()));
        String key = RedisKeyUtil.buildRedisKey(RedisKeyEnum.REFUND_PRODUCT_STRATEGY,productStrategyDO.getBizType(),
                productStrategyDO.getSubBizType());
        redisManager.deleteObject(key);
        refundProductStrategyMapper.update(refundProductStrategyDO);
    }

    /**
     * 删除产品退款策略关联表信息
     *
     * @param refundProductStrategyDO 产品退款策略关联表信息对象
     */
    public void deleteRefundProductStrategy(RefundProductStrategyDO refundProductStrategyDO) {

        refundProductStrategyMapper.deleteInfo(refundProductStrategyDO.getUpdatedBy(), refundProductStrategyDO.getId());
    }

    /**
     * 查询产品对应的退货规则，包含优先级和模式
     *
     * @param refundProductStrategyDO 产品策略关联对象
     * @return 提供给内部使用退款模式对象
     */
    public RefundProductStrategyMergeDO selectRefundProductStrategyMerge(RefundProductStrategyDO refundProductStrategyDO) {

        RefundProductStrategyMergeDO refundProductStrategyMergeDO = new RefundProductStrategyMergeDO();
        RefundProductStrategyDO productStrategyDO = redisManager.queryObjectByKey(keyStrategyProduct + refundProductStrategyDO.getBizType() + refundProductStrategyDO.getSubBizType(), RefundProductStrategyDO.class);
        if (productStrategyDO == null) {
            List<RefundProductStrategyDO> list = refundProductStrategyMapper.selectInfo(refundProductStrategyDO);
            if (list != null && list.size() > 0) {
                productStrategyDO = list.get(0);
                redisManager.insertObject(productStrategyDO, keyStrategyProduct + refundProductStrategyDO.getBizType() + refundProductStrategyDO.getSubBizType());
            }
        }
        BeanCopyUtil.copy(productStrategyDO, refundProductStrategyMergeDO);

        String strategyId = refundProductStrategyDO.getStrategyId();
        List<RefundStrategyPriorityDO> priorityList = redisManager.queryListByKey(keyStrategyPriority + strategyId, RefundStrategyPriorityDO.class);
        if (priorityList == null || priorityList.size() == 0) {
            RefundStrategyPriorityDO refundStrategyPriorityDO = new RefundStrategyPriorityDO();
            refundStrategyPriorityDO.setRefundStrategyPriority(strategyId);
            priorityList = refundStrategyPriorityMapper.selectInfo(refundStrategyPriorityDO);
            redisManager.insertObject(priorityList, keyStrategyPriority + strategyId);
        }
        refundProductStrategyMergeDO.setPriorityDOList(priorityList);

        List<RefundStrategyModeDO> strategyModeList = redisManager.queryListByKey(keyStrategyMode + strategyId, RefundStrategyModeDO.class);
        if (strategyModeList == null || strategyModeList.size() == 0) {
            RefundStrategyModeDO refundStrategyModeDO = new RefundStrategyModeDO();
            refundStrategyModeDO.setRefundStrategyMode(strategyId);
            strategyModeList = refundStrategyModeMapper.selectInfo(refundStrategyModeDO);
            redisManager.insertObject(strategyModeList, keyStrategyMode + strategyId);
        }
        refundProductStrategyMergeDO.setModeDOList(strategyModeList);

        return refundProductStrategyMergeDO;
    }


    /**
     * 根据产品业务类型查询退款策略
     *
     * @param bizType       产品大类
     * @param subBizType    产品细类
     * @return              退款策略
     */
    public List<RefundStrategyBO> queryRefundProductStrategyMerge(String bizType, String subBizType){

        log.debug("call queryRefundProductStrategyMerge Parameter,bizType:{},subBizType:{}", bizType, subBizType);

        String key = RedisKeyUtil.buildRedisKey(RedisKeyEnum.REFUND_PRODUCT_STRATEGY,bizType,subBizType);

        List<RefundStrategyBO> list = redisManager.queryListByKey(key, RefundStrategyBO.class);
        if(!CollectionUtils.isEmpty(list)){
            return list;
        }

        //1、查询产品退款策略关系信息
        RefundProductStrategyDO refundProductStrategyDO =
                refundProductStrategyMapper.selectByBizType(bizType, subBizType);
        if(null == refundProductStrategyDO){
            log.error("查询产品退款策略失败，error:{}",PayCoreErrorCode.REFUND_PRODUCT_PRIORITY_IS_NULL);
            throw new PayCoreManagerException(PayCoreErrorCode.REFUND_PRODUCT_PRIORITY_IS_NULL);
        }

        //2、根据退款策略Id，查询退款策略
        RefundStrategyDO refundStrategyDO =
                refundStrategyMapper.selectById(Long.parseLong(refundProductStrategyDO.getStrategyId()));
        if(null == refundStrategyDO){
            log.error("查询产品退款策略失败，error:{}",PayCoreErrorCode.REFUND_STRATEGY_IS_NULL);
            throw new PayCoreManagerException(PayCoreErrorCode.REFUND_STRATEGY_IS_NULL);
        }

        //3、根据退款模式配置信息，查询退款模式信息对象
        List<RefundStrategyModeDO> refundStrategyModeDOs =
                refundStrategyModeMapper.selectByRefundStrategyMode(refundStrategyDO.getRefundStrategyMode());
        if(CollectionUtils.isEmpty(refundStrategyModeDOs)){
            log.error("查询产品退款策略失败，error:{}",PayCoreErrorCode.REFUND_STRATEGY_MODE_IS_NULL);
            throw new PayCoreManagerException(PayCoreErrorCode.REFUND_STRATEGY_MODE_IS_NULL);
        }
        //退款方向校验
        RefundCheckUtil.refundStrategyCheck(refundStrategyModeDOs);


        //4、根据退款退款优先级配置,查询退款策略优先级配置信息
        List<RefundStrategyPriorityDO> refundStrategyPriorityDOs = refundStrategyPriorityMapper.
                selectByRefundStrategyPriority(refundStrategyDO.getRefundStrategyPriority(),
                        UsableFlagEnum.USABLE.getCode());
        if(CollectionUtils.isEmpty(refundStrategyPriorityDOs)){
            log.error("查询产品退款策略失败，error:{}",PayCoreErrorCode.REFUND_PRIORITY_IS_NULL);
            throw new PayCoreManagerException(PayCoreErrorCode.REFUND_PRIORITY_IS_NULL);
        }

        //5、组装产品退款策略对象
        list = new ArrayList<>();

        for(RefundStrategyModeDO refundStrategyModeDO : refundStrategyModeDOs){
            list.add(getRefundProductStrategyBO(refundProductStrategyDO,refundStrategyModeDO,refundStrategyPriorityDOs));
        }
        CollectionUtils.sort(list);

        redisManager.insertObject(list,key);

        log.debug("退款策略查询结果, result:{}",list);
        return list;
    }

    /**
     * 构建产品退款策略关联信息对象
     *
     * @param refundProductStrategyDO      产品退款策略关联信息对象
     * @param refundStrategyModeDO         统一支付退款模式信息对象
     * @param refundStrategyPriorityDOs    退款策略优先级配置信息集合
     * @return                             产品退款策略关联信息对象
     */
    public RefundStrategyBO getRefundProductStrategyBO(RefundProductStrategyDO refundProductStrategyDO,
                                                       RefundStrategyModeDO refundStrategyModeDO,
                                                       List<RefundStrategyPriorityDO> refundStrategyPriorityDOs){

        for(RefundStrategyPriorityDO refundStrategyPriorityDO : refundStrategyPriorityDOs){
            if(StringUtils.equals(refundStrategyModeDO.getPayToolType(),refundStrategyPriorityDO.getPayToolType())){

                return DO2BOConverter.getRefundProductStrategyBO(refundProductStrategyDO,
                        refundStrategyModeDO,refundStrategyPriorityDO);
            }
        }
        throw new PayCoreManagerException(PayCoreErrorCode.REFUND_STRATEGY_CONFIG_ERROR);
    }
}
